package com.zenithmind.classroom.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.classroom.mapper.CourseLessonMapper;
import com.zenithmind.classroom.pojo.dto.LessonCreateDTO;
import com.zenithmind.classroom.pojo.dto.LessonUpdateDTO;
import com.zenithmind.classroom.pojo.dto.LessonQueryDTO;
import com.zenithmind.classroom.pojo.domain.CourseLesson;
import com.zenithmind.classroom.pojo.vo.LessonDetailVO;
import com.zenithmind.classroom.pojo.vo.LessonVO;
import com.zenithmind.classroom.service.CourseLessonService;
import com.zenithmind.common.result.PageResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 课程课时服务实现类
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class CourseLessonServiceImpl extends ServiceImpl<CourseLessonMapper, CourseLesson> implements CourseLessonService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    public LessonVO createLesson(LessonCreateDTO createDTO) {
        log.info("创建课时: {}", createDTO.getTitle());
        
        CourseLesson lesson = new CourseLesson();
        BeanUtils.copyProperties(createDTO, lesson);
        
        // 设置排序值
        if (lesson.getSortOrder() == null) {
            Integer maxSortOrder = baseMapper.getMaxSortOrder(createDTO.getChapterId());
            lesson.setSortOrder(maxSortOrder + 1);
        }
        
        lesson.setCreateTime(LocalDateTime.now());
        lesson.setUpdateTime(LocalDateTime.now());
        
        save(lesson);
        
        return convertToVO(lesson);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateLesson(String id, LessonUpdateDTO updateDTO) {
        log.info("更新课时: {}", id);
        
        CourseLesson lesson = getById(id);
        if (lesson == null) {
            throw new RuntimeException("课时不存在");
        }
        
        BeanUtils.copyProperties(updateDTO, lesson);
        lesson.setUpdateTime(LocalDateTime.now());
        
        return updateById(lesson);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteLesson(String id) {
        log.info("删除课时: {}", id);
        
        CourseLesson lesson = getById(id);
        if (lesson == null) {
            throw new RuntimeException("课时不存在");
        }
        
        // 软删除
        lesson.setIsDeleted(1);
        lesson.setUpdateTime(LocalDateTime.now());
        
        return updateById(lesson);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean publishLesson(String id) {
        log.info("发布课时: {}", id);
        
        CourseLesson lesson = getById(id);
        if (lesson == null) {
            throw new RuntimeException("课时不存在");
        }
        
        lesson.setStatus(1); // 已发布
        lesson.setPublishTime(LocalDateTime.now());
        lesson.setUpdateTime(LocalDateTime.now());
        
        return updateById(lesson);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean unpublishLesson(String id) {
        log.info("下架课时: {}", id);

        CourseLesson lesson = getById(id);
        if (lesson == null) {
            throw new RuntimeException("课时不存在");
        }

        lesson.setStatus(2); // 已下架
        lesson.setUpdateTime(LocalDateTime.now());

        return updateById(lesson);
    }

    @Override
    public List<LessonVO> getChapterLessons(String chapterId, String userId, Boolean includeUnpublished) {
        log.info("获取章节课时列表: chapterId={}, userId={}", chapterId, userId);
        
        return baseMapper.selectChapterLessonsWithProgress(chapterId, userId, includeUnpublished);
    }

    @Override
    public List<LessonVO> getCourseLessons(String courseId, String userId, Boolean includeUnpublished) {
        log.info("获取课程课时列表: courseId={}, userId={}", courseId, userId);
        
        return baseMapper.selectCourseLessonsWithProgress(courseId, userId, includeUnpublished);
    }

    @Override
    public LessonDetailVO getLessonDetail(String id, String userId) {
        log.info("获取课时详情: id={}, userId={}", id, userId);
        
        return baseMapper.selectLessonDetailWithProgress(id, userId);
    }

    @Override
    public String getLessonPlayUrl(String id, String userId) {
        log.info("获取课时播放地址: id={}, userId={}", id, userId);
        
        return baseMapper.getLessonPlayUrl(id, userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean reorderLessons(String chapterId, List<String> lessonIds) {
        log.info("调整课时顺序: chapterId={}", chapterId);
        
        return baseMapper.batchUpdateLessonOrder(lessonIds, chapterId) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean moveLesson(String id, String targetChapterId, Integer sortOrder) {
        log.info("移动课时: id={}, targetChapterId={}", id, targetChapterId);
        
        return baseMapper.moveLessonToChapter(id, targetChapterId, sortOrder) > 0;
    }

    @Override
    public LessonVO copyLesson(String id, String targetChapterId, String title) {
        log.info("复制课时: id={}, targetChapterId={}", id, targetChapterId);
        
        String newLessonId = baseMapper.copyLesson(id, targetChapterId, title, null);
        CourseLesson newLesson = getById(newLessonId);
        
        return convertToVO(newLesson);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean uploadLessonResource(String id, String resourceType, String resourceUrl, Long resourceSize) {
        log.info("上传课时资源: id={}, type={}", id, resourceType);
        
        return baseMapper.uploadLessonResource(id, resourceType, resourceUrl, resourceSize) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean recordLessonWatch(String id, String userId, Integer watchTime, Integer position) {
        log.info("记录课时观看: id={}, userId={}", id, userId);
        
        return baseMapper.recordLessonWatch(id, userId, watchTime, position) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean completeLessonStudy(String id, String userId) {
        log.info("完成课时学习: id={}, userId={}", id, userId);
        
        return baseMapper.completeLessonStudy(id, userId) > 0;
    }

    @Override
    public LessonVO getNextLesson(String id, String userId) {
        log.info("获取下一个课时: id={}, userId={}", id, userId);
        
        return baseMapper.selectNextLesson(id, userId);
    }

    @Override
    public LessonVO getPreviousLesson(String id, String userId) {
        log.info("获取上一个课时: id={}, userId={}", id, userId);
        
        return baseMapper.selectPreviousLesson(id, userId);
    }

    @Override
    public Object getLessonStatistics(String id) {
        log.info("获取课时统计: {}", id);
        
        // TODO: 实现课时统计逻辑
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateLessonStatistics(String id) {
        log.info("更新课时统计: {}", id);
        
        return baseMapper.updateLessonStatistics(id) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer batchImportLessons(List<LessonCreateDTO> lessons) {
        log.info("批量导入课时: {}", lessons.size());
        
        int count = 0;
        for (LessonCreateDTO createDTO : lessons) {
            try {
                createLesson(createDTO);
                count++;
            } catch (Exception e) {
                log.error("导入课时失败: {}", createDTO.getTitle(), e);
            }
        }
        
        return count;
    }

    @Override
    public List<LessonVO> exportLessons(List<String> lessonIds) {
        log.info("导出课时: {}", lessonIds);

        LambdaQueryWrapper<CourseLesson> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(CourseLesson::getId, lessonIds)
                .eq(CourseLesson::getIsDeleted, 0);

        List<CourseLesson> lessons = list(wrapper);
        return lessons.stream().map(this::convertToVO).toList();
    }

    @Override
    public Integer getLessonProgress(String lessonId, String userId) {
        log.info("获取课时学习进度: lessonId={}, userId={}", lessonId, userId);

        // TODO: 实现课时学习进度查询
        // 这里需要查询学习进度表
        return 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer batchCreateLessons(List<LessonCreateDTO> lessons) {
        log.info("批量创建课时: {}", lessons.size());

        int count = 0;
        for (LessonCreateDTO createDTO : lessons) {
            try {
                createLesson(createDTO);
                count++;
            } catch (Exception e) {
                log.error("创建课时失败: {}", createDTO.getTitle(), e);
            }
        }

        return count;
    }

    @Override
    public List<LessonVO> getChapterLessons(String chapterId, Boolean includeUnpublished) {
        log.info("获取章节课时列表: chapterId={}, includeUnpublished={}", chapterId, includeUnpublished);

        LambdaQueryWrapper<CourseLesson> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CourseLesson::getChapterId, chapterId)
                .eq(CourseLesson::getIsDeleted, 0);

        if (!includeUnpublished) {
            wrapper.eq(CourseLesson::getIsPublished, 1);
        }

        wrapper.orderByAsc(CourseLesson::getSortOrder);

        List<CourseLesson> lessons = list(wrapper);
        return lessons.stream().map(this::convertToVO).toList();
    }

    @Override
    public List<LessonVO> getCourseLessons(String courseId, Boolean includeUnpublished) {
        log.info("获取课程课时列表: courseId={}, includeUnpublished={}", courseId, includeUnpublished);

        LambdaQueryWrapper<CourseLesson> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CourseLesson::getCourseId, courseId)
                .eq(CourseLesson::getIsDeleted, 0);

        if (!includeUnpublished) {
            wrapper.eq(CourseLesson::getIsPublished, 1);
        }

        wrapper.orderByAsc(CourseLesson::getSortOrder);

        List<CourseLesson> lessons = list(wrapper);
        return lessons.stream().map(this::convertToVO).toList();
    }

    @Override
    public PageResult<LessonVO> getLessonPage(LessonQueryDTO queryDTO) {
        log.info("分页查询课时: {}", queryDTO);
        
        // 创建分页对象
        Page<CourseLesson> page = queryDTO.toPage();
        
        // 构建查询条件
        LambdaQueryWrapper<CourseLesson> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.hasText(queryDTO.getChapterId()), CourseLesson::getChapterId, queryDTO.getChapterId())
                    .eq(StringUtils.hasText(queryDTO.getCourseId()), CourseLesson::getCourseId, queryDTO.getCourseId())
                    .like(StringUtils.hasText(queryDTO.getTitle()), CourseLesson::getTitle, queryDTO.getTitle())
                    .eq(queryDTO.getStatus() != null, CourseLesson::getStatus, queryDTO.getStatus())
                    .eq(queryDTO.getType() != null, CourseLesson::getType, queryDTO.getType())
                    .orderByAsc(CourseLesson::getSortOrder)
                    .orderByDesc(CourseLesson::getCreateTime);
        
        // 执行分页查询
        Page<CourseLesson> lessonPage = page(page, queryWrapper);
        
        // 转换为VO对象
        List<LessonVO> lessonVOList = lessonPage.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
        
        // 返回分页结果
        return new PageResult<>(lessonVOList, lessonPage.getTotal(), lessonPage.getCurrent(), lessonPage.getSize());
    }

    /**
     * 转换为VO
     */
    private LessonVO convertToVO(CourseLesson lesson) {
        LessonVO vo = new LessonVO();
        BeanUtils.copyProperties(lesson, vo);
        
        // 设置状态名称
        vo.setStatusName(getStatusName(lesson.getStatus()));
        vo.setTypeName(getTypeName(lesson.getType()));
        
        // TODO: 补充其他字段转换
        
        return vo;
    }

    private String getStatusName(Integer status) {
        if (status == null) return "未知";
        switch (status) {
            case 0: return "草稿";
            case 1: return "已发布";
            case 2: return "已下架";
            default: return "未知";
        }
    }

    private String getTypeName(Integer type) {
        if (type == null) return "未知";
        switch (type) {
            case 1: return "视频";
            case 2: return "音频";
            case 3: return "文档";
            case 4: return "图文";
            case 5: return "直播";
            case 6: return "作业";
            case 7: return "测验";
            default: return "未知";
        }
    }
}
